<?php

/**
 * Élément de base des objets
 *
 * @package cass
 * @author Mickaël CASTANHEIRO <mickael.castanheiro@gmail.com>
 * @version 1.0
 */

namespace cass;

final class Uri extends Structure {

    public $uri;
    public $package;
    public $action;
    public $request;
    public $parameters;

    /**
     * Constructeur de la classe
     * Indique que les paramètres sont sous forme de tableau
     */
    public function __construct() {
	$this->uri = Data::directories('uri');
	$this->package = Data::actions('defaultPackage');
	$this->action = Data::actions('defaultAction');
	$this->request = Data::actions('defaultRequest');
	$this->parameters = array();
    }

    /**
     * Crée une structure depuis les paramètres
     * @param String $_package
     * @param String $_action
     * @param String $_request
     * @param Array $_parameters
     */
    static public function create() {
	$args = func_get_args();
	$p = new Uri;

	if (empty($args) OR !is_array($args)) {
	    return $p;
	}

	// Déjà un Uri
	if ( (sizeof($args)==1) AND ($args[0] instanceof Uri) ) {
	    return $args[0]; // Retourne l'uri
	}

	// Tableau passé
	if ((sizeof($args) == 1) AND is_array($args[0])) {
	    $args = $args[0];
	    if (!empty($args[0]))
		$p->package = $args[0];
	    if (!empty($args[1]))
		$p->action = $args[1];
	    if (!empty($args[2]))
		$p->request = $args[2];
	    if (!empty($args[3]))
		$p->parameters = (is_array($args[3])) ? $args[3] : array($args[3]);

	    return $p;
	}

	// Chaîne @
	if (substr($args[0], 0, 1) == '@') {
	    switch ($args[0]) {
		case '@homepage':
		    return $p;
		    break;

		case '@404':
		    return self::create(\cass\Data::actions('errorPackage'), \cass\Data::actions('errorAction'), \cass\Data::actions('error404'));
		    break;

		case '@403':
		    return self::create(\cass\Data::actions('errorPackage'), \cass\Data::actions('errorAction'), \cass\Data::actions('error403'));
		    break;

		case '@register':
		    return self::create(\cass\Data::actions('errorPackage'), 'register');

		default:
		    return $p;
		    break;
	    }
	}

	if (!empty($args[0]))
	    $p->package = $args[0];
	if (!empty($args[1]))
	    $p->action = $args[1];
	if (!empty($args[2]))
	    $p->request = $args[2];
	if (!empty($args[3]))
	    $p->parameters = (is_array($args[3])) ? $args[3] : array($args[3]);
	return $p;
    }

    /**
     * Analyse l'url pour déterminer le package, l'action, la request et les paramètres
     * @param <string> $_uri Url à analyser
     */
    static public function createFromURI($_uri) { 
	$package = Data::actions('defaultPackage');
	$action = Data::actions('defaultAction');
	$request = Data::actions('defaultRequest');
	$parameters = array();

	preg_match('!/'.Data::directories('relative_uri').'(?:(?:(?P<package>[-_\w]+)/)?)(?:(?:(?P<action>[-,_\w]+)\.html)?)!i', $_uri, $matches);

	// Package spécifié
	if (!empty($matches['package'])) {
	    $package = $matches['package'];
	}

	// Action spécifiée, on en extrait les paramètres depuis la première ,
	if (!empty($matches['action'])) {
	    $actions = explode(',', $matches['action']);
	    $action = $actions[0];
	    $parameters = array_slice($actions, 1);
	}

	// On sépare l'action de la request depuis le dernier -
	$actions = explode('-', $action);
	$action = $actions[0];
	if (!empty($actions[1])) {
	    $request = implode('-', array_slice($actions, 1));
	}

	return self::create($package, $action, $request, $parameters);
    }

    public function getLink() {
	$package = ($this->package == Data::actions('defaultPackage') ) ?
		'' :
		$this->package . '/';

	$action = ( ($this->request == Data::actions('defaultRequest')) AND ($this->action == Data::actions('defaultAction')) AND empty($this->parameters) ) ?
		'' :
		$this->action;

	$request = ( $this->request == Data::actions('defaultRequest') ) ?
		'' :
		'-' . $this->request;

	$parameters = ( empty($this->parameters) ) ?
		'' :
		',' . implode(',', $this->parameters);

	$extension = ( empty($action) ) ?
		'' :
		Data::extensions('html');

	return $package . $action . $request . $parameters . $extension;
    }

    public function getLinkAddingParameters($_parameter = array()) {
	if (!is_array($_parameter)) {
	    $_parameter = array($_parameter);
	}

	$package = ($this->package == Data::actions('defaultPackage') ) ?
		'' :
		$this->package . '/';

	$action = ( ($this->request == Data::actions('defaultRequest')) AND ($this->action == Data::actions('defaultAction')) AND empty($this->parameters) ) ?
		'' :
		$this->action;

	$request = ( $this->request == Data::actions('defaultRequest') ) ?
		'' :
		'-' . $this->request;

	$parameters = ',' . implode(',', array_merge($this->parameters, $_parameter));

	$extension = ( empty($action) ) ?
		'' :
		Data::extensions('html');

	return $package . $action . $request . $parameters . $extension;
    }

}
